package com.xjy.study.tdd;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by xujieyang on 2016/12/12.
 */
public class TemplateParser {

    // 抽象层次：将templateText切割成纯文本和变量
    public List<String> parse(String templateText) {
        List<String> segments = new ArrayList<>();
        int index = parseTemplateToSegments(templateText, segments);

        addToTail(templateText, segments, index);

        addEmptyString(segments);

        return segments;
    }

    private int parseTemplateToSegments(String templateText, List<String> segments) {
        Matcher matcher = buildMatcher(templateText);

        int index = 0;
        while(matcher.find()) {
            addPlainTextToSegments(templateText, segments, index, matcher);

            addVariableToSegments(templateText, segments, matcher);

            index = matcher.end();
        }
        return index;
    }

    private void addVariableToSegments(String templateText, List<String> segments, Matcher matcher) {
        segments.add(templateText.substring(matcher.start(), matcher.end()));
    }

    private void addPlainTextToSegments(String templateText, List<String> segments, int index, Matcher matcher) {
        if(index != matcher.start()) {
            segments.add(templateText.substring(index, matcher.start()));
        }
    }

    private Matcher buildMatcher(String templateText) {
        String regex = "\\$\\{[^}]*\\}";
        return Pattern.compile(regex).matcher(templateText);
    }

    /**
     * 将剩余的纯文本添加到segments末尾
     * @param templateText
     * @param segments
     * @param index
     */
    private void addToTail(String templateText, List<String> segments, int index) {
        if(index < templateText.length()) {
            segments.add(templateText.substring(index));
        }
    }

    /**
     * 如果segments为空，添加一个空字符串
     * @param segments
     */
    private void addEmptyString(List<String> segments) {
        if(segments.isEmpty()) {
            segments.add("");
        }
    }

}
